/*!
 * \file util.cc
 *
 * \brief Implementation for the util classes/routines
 *
 * \date Started: 9/13/10
 * \date Last Modified: 9/13/10
 * \authors Alan LaMielle
 *
 * Copyright (c) 2010, Colorado State University <br>
 * All rights reserved. <br>
 * See ../../COPYING for details. <br>
 */

#include <iegenlib/iegenlib.h>

namespace iegenlib{

string createUniqueName(string name, set<string> taken) {
   //Is the name already taken?
   if(taken.find(name) == taken.end()){
      return name;
   }

   int count = 1;
   string retval;

   //loop until we find a unique name
   do {
      stringstream ss;
      ss << name << count++;
      retval = ss.str();
   } while(taken.find(retval) != taken.end());
   return retval;
}

list<string> createUniqueNames(list<string>::const_iterator begin,
                              list<string>::const_iterator end,
                              set<string>& symbols,
                              map<string,string>& old2new) {

   list<string> new_names;

   //Grab each string in the given sequence
   for(list<string>::const_iterator itr = begin; itr != end; ++itr) {
      string curr_name=*itr,new_name;

      //Is the current name already taken?
      if(symbols.find(curr_name) != symbols.end()) {
         //Create a new unique name for the current name
         new_name=createUniqueName(curr_name,symbols);
         //Add the new name to the list of new names and set of reserved symbols
         new_names.push_back(new_name);
         symbols.insert(new_name);
      }
      else {
         //Add the name to the list of new names and set of reserved symbols
         new_name=curr_name;
         new_names.push_back(curr_name);
         symbols.insert(curr_name);
      }

      //Add to the rename mapping whether we renamed or not
      old2new[curr_name]=new_name;
   }

   return new_names;
}

void createMatchingNames(list<string>::const_iterator match_begin,
                         list<string>::const_iterator match_end,
                         list<string>::const_iterator names_begin,
                         list<string>::const_iterator names_end,
                         map<string,string>& old2new) {

   //Iterate over pairs of names
   list<string>::const_iterator match_itr;
   list<string>::const_iterator names_itr;
   for(match_itr=match_begin,names_itr=names_begin;
       match_itr!=match_end && names_itr!=names_end;
       ++match_itr,++names_itr) {
      old2new[*names_itr]=*match_itr;
   }
}

set<string> unionNamesLists(list<string> const& l1,list<string> const& l2)
{
   set<string> unioned;
   unioned.insert(l1.begin(),l1.end());
   unioned.insert(l2.begin(),l2.end());
   return unioned;
}

list<TupleType> renameTupleVars(list<TupleType>::const_iterator begin,
                                list<TupleType>::const_iterator end,
                                map<string,string> renameMap) {
   list<TupleType> new_tuple_vars;
   for(list<TupleType>::const_iterator itr=begin; itr!=end; itr++) {
      TupleType tuple_var=*itr;
      if(tuple_var.isVar()) {
         new_tuple_vars.push_back(TupleType(renameMap[tuple_var.getName()]));
      }
      else {
         new_tuple_vars.push_back(tuple_var);
      }
   }
   return new_tuple_vars;
}

}//end namespace iegenlib
